package com.hgits.hotc.web.controller;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageInfo;
import com.hgits.hotc.common.properties.HotcProperties;
import com.hgits.hotc.entity.*;
import com.hgits.hotc.entity.enums.ImportResult;
import com.hgits.hotc.entity.enums.Summation;
import com.hgits.hotc.service.ImportService;
import com.hgits.hotc.service.LogService;
import com.hgits.hotc.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

@Slf4j
@Controller
@RequestMapping("/api/v1/import")
public class ImportController {

    private static final Map<String, Class<?>> fileName2EntityMap = new HashMap<>();

    static {
        fileName2EntityMap.put("DataPointSum", DataPointSumSend.class);
        fileName2EntityMap.put("EnPass", EnPassSend.class);
        fileName2EntityMap.put("ExEtcTrans", ExEtcTransSend.class);
        fileName2EntityMap.put("ExPass", ExPassSend.class);
        fileName2EntityMap.put("GantryCount", GantryCountSend.class);
        fileName2EntityMap.put("GantryTrans", GantryTransSend.class);
        fileName2EntityMap.put("LaneEnCount", LaneEnCountSend.class);
        fileName2EntityMap.put("LaneExCount", LaneExCountSend.class);
        fileName2EntityMap.put("LaneShift", LaneShiftSend.class);
        fileName2EntityMap.put("OtherTrans", OtherTransSend.class);
        fileName2EntityMap.put("VehIdImageOnDemand", VehIdImageOnDemandSend.class);
        fileName2EntityMap.put("VehIdInfo", VehIdInfoSend.class);
    }

    @Resource
    HotcProperties hotcProperties;

    @Resource
    LogService logService;

    @Resource
    ImportService importService;

    @Resource
    ExtractUtil extractUtil;

    private static Integer type;

    @RequestMapping("/index")
    public String index(HttpServletRequest request, HttpServletResponse response, Integer page, Integer limit, @RequestParam(value = "sumType",required = false) Integer sumType){
        if (null!=sumType){
            type=sumType;
        }
        if (request.getMethod().toUpperCase().equals("GET")){
            return "index";
        }

        PageInfo<Log> logs = extractUtil.log(type, page, limit);
        LayUIPageInfo<Log> logLayUIPageInfo=new LayUIPageInfo<Log>(0,"处理成功",logs.getList());
/*        Map result = new HashMap();
        result.put("data",logs);
        result.put("count",logs.getTotal());//总页数
        result.put("code","0");//必须写
        result.put("LAY_TABLE_INDEX",0);*/
        try {
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-type","application/json; charset=utf-8");
            PrintWriter out = response.getWriter();
            out.write(JSON.toJSONString(logLayUIPageInfo));
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }





    @PostMapping("/persist")
    public String  importFlowAboutNaturalSum(@RequestParam("file") MultipartFile file, Model model) throws Exception {
        //一. 读取文件名，然后进行文件名校验及MD5码校验
        //二. 读取压缩包中文件的内容，将每种类型的文件进行插库   完成
        //三. 在插库操作中，保证事务性，若中间有插入失败，则回滚，返回插入失败 完成
        if(file.isEmpty()){
            model.addAttribute("msg","未选择文件！请重新选择文件");
            return "index";
        }

        String originalFilename = file.getOriginalFilename();
        int begin = originalFilename.indexOf(".");
        int last = originalFilename.length();
        String typeName = originalFilename.substring(begin, last);
        if(!typeName.equals(".zip")){
            model.addAttribute("msg","上传文件不是zip文件，请上传zip类型文件！");
            return "index";
        }
        String fileNameNoEx = FileUtils.getFileNameNoEx(originalFilename);

        Log aLog = getLog(originalFilename);

        InputStream inputStream = file.getInputStream();

        String tmpDir = hotcProperties.getTmpDir();
        String parent = tmpDir + File.separator + fileNameNoEx;

        //1. 将压缩文件解压到指定目录
        ZipUtils.unzip(parent, inputStream);

        //2. 校验文件的MD5码
        boolean md5Flag = extractUtil.checkMD5(parent);
        if(!md5Flag){
            model.addAttribute("msg","MD5校验错误");
            return "index";
        }

        //3. 从指定目录提取文件
        List<File> files = FileUtils.getFilesFrom(parent);

        //4. 将文件转化成相应的实体类
        if(files == null) {
            model.addAttribute("msg","文件转化成相应的实体类错误");
            return "index";
        }
        Map<Class<?>, List<?>> entityListMap = new HashMap<>();

        for (File f : files) {
            Class<?> aClass = getClass(f);
            List<?> objects = BeanUtils.transferTo(f, aClass);
            entityListMap.put(aClass, objects);
        }

        //5. 尝试将解压缩的文件进行入库
        try {
            importService.saveData(entityListMap);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("发生异常：{}", e.getMessage());
            aLog.setResult(ImportResult.FAIL.getCode());
            model.addAttribute("msg","入库失败");
            return "index";
        } finally {
        //6. 插入日志
            logService.insert(aLog);

        //7. 删除解析文件
            FileUtils.deleteDirectory(new File(parent));
        }
        model.addAttribute("msg","入库成功");
        return "index";
    }

    private Log getLog(String originalFilename) {
        // fotc_naturalsum_4401_2402_7_91F3FE105B41CEE5880D747C72C8BA92_20200301
        String[] splits = originalFilename.split("_");
        Integer sumType = Summation.SQUAD.getDesc().equals(splits[1])
                ? Summation.SQUAD.getCode() : Summation.NATURAL.getCode();

        String str = splits[3];
        Integer roadNo = Integer.valueOf(str.substring(0, 2));
        Integer stationNo = Integer.valueOf(str.substring(2, 4));

        Log log = new Log();

        log.setId(UUID.randomUUID().toString().replaceAll("-",""))
            .setFileName(originalFilename)
            .setSumType(sumType)
            .setRoadNo(roadNo)
            .setStationNo(stationNo)
            .setImportTime(new Date())
            .setResult(ImportResult.SUCCESS.getCode());
        return log;
    }

    private Class<?> getClass(File file) {
        String fileName = file.getName();
        int i = fileName.indexOf('_');
        String key = fileName.substring(i + 1, fileName.indexOf('_', i + 1));
        return fileName2EntityMap.get(key);
    }

}
